package com.xhwl.centiotdata.suppliersystem.bosiny;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.constant.BosinyConstant;
import com.xhwl.centiotdata.pojo.dto.bosiny.BosinyDeviceDTO;
import com.xhwl.centiotdata.pojo.dto.bosiny.BosinyOpenRecordsDTO;
import com.xhwl.centiotdata.pojo.dto.pedestrian.PedestrianIntegrationConfigDTO;
import com.xhwl.centiotdata.utils.ThreadPoolUtils;
import com.xhwl.common.dto.auth.PedestrianAuthDTO;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.dto.cent.pedes.OpenDoorRecordDTO;
import com.xhwl.common.enums.AccessTypeEnum;
import com.xhwl.common.enums.DirectionEnum;
import com.xhwl.common.enums.ProductEnum;
import com.xhwl.common.enums.SupplierEnum;
import com.xhwl.common.utils.ChkUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.FutureTask;

/**
 * Falcon.cao @Copyright (C), 2022, 兴海物联
 * Date: 2022/6/11 15:17
 * Description: 博西尼门禁系统对接
 */
@Slf4j
@Service
public class PedestrianBosinyHandler {

    @Autowired
    private GeneralBosinyHandler generalBosinyHandler;

    @Autowired
    private DeviceBosinyHandler deviceBosinyHandler;

    public String openDoor(PedestrianIntegrationConfigDTO config, DeviceDTO device) {
        JSONObject params = new JSONObject();
        params.put(BosinyConstant.PARAM_STATE, "2");
        params.put(BosinyConstant.PARAM_CODE, device.getThirdDeviceId());
        JSONObject result = generalBosinyHandler.execute(config, params, BosinyConstant.NAME_LOCK_STATE_SET, "2.0");
        if ("0".equals(result.getString("code"))) {
            return "SUCCESS";
        }
        return result.getString("msg");
    }

    public String pushCard(PedestrianIntegrationConfigDTO config, List<DeviceDTO> devices, PedestrianAuthDTO auth) {
//        log.info("开始创建博西尼卡片授权：{} - {}", JSON.toJSONString(devices), JSON.toJSONString(auth));
        ThreadPoolUtils.pedestrianExecutor.execute(() -> {
            for (DeviceDTO device : devices) {
                if (!ProductEnum.BOSINY.getId().equals(device.getProductId())) {
                    continue;
                }
                List<String> list = Optional.ofNullable(auth.getCardNumberList()).orElse(new LinkedList<>());
                if (auth.getCardNumber() != null) {
                    list.add(auth.getCardNumber());
                }
                for (String item : list) {
                    JSONObject params = new JSONObject();
                    params.put(BosinyConstant.PARAM_TYPE, 1);
                    params.put(BosinyConstant.PARAM_STYLE, 1);
                    params.put(BosinyConstant.PARAM_CARD_NUMBER, item);
                    params.put(BosinyConstant.PARAM_START_TIME, auth.getValidStartTime());
                    params.put(BosinyConstant.PARAM_END_TIME, auth.getValidEndTime());
                    params.put(BosinyConstant.PARAM_ASSIGNEE_NAME, auth.getUserDTO().getName());
                    params.put(BosinyConstant.PARAM_ASSIGNEE_MOBILE, auth.getUserDTO().getPhone());
                    params.put(BosinyConstant.PARAM_CODE, device.getThirdDeviceId());
                    JSONObject execute = generalBosinyHandler.execute(config, params, BosinyConstant.NAME_LOCK_CARD_ADD, "2.0");
                    log.info("博西尼下发卡片2.0 请求结果：{}", execute);
                }
            }
        });
        return "SUCCESS";
    }

    public String delsCard(PedestrianIntegrationConfigDTO config, List<DeviceDTO> devices, PedestrianAuthDTO auth) {
        for (DeviceDTO device : devices) {
            ThreadPoolUtils.pedestrianExecutor.execute(() -> {
                List<String> list = Optional.ofNullable(auth.getCardNumberList()).orElse(new LinkedList<>());
                if (auth.getCardNumber() != null) {
                    list.add(auth.getCardNumber());
                }
                for (String item : list) {
                    JSONObject params = new JSONObject();
                    params.put(BosinyConstant.PARAM_TYPE, 1);
                    params.put(BosinyConstant.PARAM_STYLE, 2);
                    params.put(BosinyConstant.PARAM_CARD_NUMBER, item);
                    params.put(BosinyConstant.PARAM_CODE, device.getThirdDeviceId());
                    generalBosinyHandler.execute(config, params, BosinyConstant.NAME_LOCK_CARD_DEL, "2.0");
                }
            });
        }
        return "SUCCESS";
    }

    public List<OpenDoorRecordDTO> pullRecord(PedestrianIntegrationConfigDTO config) {
        List<BosinyDeviceDTO> devices = deviceBosinyHandler.getDevicesSN(config);

        Map<BosinyDeviceDTO, FutureTask<JSONObject>> futures = new LinkedHashMap<>();
        for (BosinyDeviceDTO dto : devices) {
            FutureTask<JSONObject> task = new FutureTask<>(() -> {
                JSONObject params = new JSONObject();
                params.put(BosinyConstant.PARAM_CODE, dto.getSn());
                params.put(BosinyConstant.PARAM_TIME_TYPE, "0");
                return generalBosinyHandler.execute(config, params, BosinyConstant.NAME_LOCK_OPEN_RECORD, "");
            });
            futures.put(dto, task);
            ThreadPoolUtils.pedestrianExecutor.submit(task);
        }

        List<OpenDoorRecordDTO> record = new LinkedList<>();
        for (Map.Entry<BosinyDeviceDTO, FutureTask<JSONObject>> entry : futures.entrySet()) {
            try {
                JSONObject object = entry.getValue().get();
                addRecords(record, config, entry.getKey(), object);
            } catch (Exception e) {
                log.error("拉取开门记录失败：{}", e.getMessage());
            }
        }
        return record;
    }

    private void addRecords(List<OpenDoorRecordDTO> records, PedestrianIntegrationConfigDTO config, BosinyDeviceDTO device, JSONObject results) {
        if (!"0".equals(results.getString("code"))) {
            return;
        }
        JSONArray array = results.getJSONArray("data");
        if (array.isEmpty()) {
            return;
        }
        List<BosinyOpenRecordsDTO> dtos = array.toJavaList(BosinyOpenRecordsDTO.class);
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        for (BosinyOpenRecordsDTO dto : dtos) {
            OpenDoorRecordDTO recordDTO = new OpenDoorRecordDTO();
            recordDTO.setCode(device.getSn() + "-" + dto.getLastOpenTime());
            recordDTO.setDirection(DirectionEnum.UNKNOWN.getId());
            recordDTO.setUserName(dto.getOperatorName());
            recordDTO.setOpenDeviceId(device.getSn());
            recordDTO.setSupplierId(SupplierEnum.BOSINY.getId());
            recordDTO.setArrivalTime(format.format(new Date(dto.getLastOpenTime())));
            recordDTO.setDeviceName("门锁" + device.getSn());
            recordDTO.setSupplierId(SupplierEnum.BOSINY.getId());
            recordDTO.setProductId(ProductEnum.BOSINY.getId());
            recordDTO.setProjectId(config.getProjectId());
            recordDTO.setState(Boolean.TRUE.equals(dto.getUnlockResult()) ? (short) 1 : (short) 0);
            recordDTO.setType(getAccessType(ChkUtil.notnull(dto.getUnlockType(), 0)));
            records.add(recordDTO);
        }
    }

    /**
     * 开锁方式:0-单次密码; 1-限时密码; 2-固定密码,3-IC卡,4-身份证,5-钥匙,6-远程,7-APP,8-小程序,9-永久密码,10-指纹密码
     */
    private Short getAccessType(int type) {
        if (type == 3) {
            return AccessTypeEnum.IC_CARD.getId();
        }
        if (type == 6 || type == 7 || type == 8) {
            return AccessTypeEnum.REMOTE.getId();
        }
        if (type == 10) {
            return AccessTypeEnum.FINGERPRINT.getId();
        }
        if (type == 5) {
            return AccessTypeEnum.MANUAL.getId();
        }
        if (type == 0 || type == 1 || type == 2 || type == 9) {
            return AccessTypeEnum.PASS_WORD.getId();
        }
        return AccessTypeEnum.OTHER.getId();
    }

}
